package com.hfzy.ihk.web.linkcall.biz.flow.config;

import com.google.common.collect.Lists;
import com.hfzy.ihk.common.constants.GlobalStatic;
import com.hfzy.ihk.common.core.elasticsearch.EsQueryUtils;
import com.hfzy.ihk.common.core.elasticsearch.service.EsBaseServiceImpl;
import com.hfzy.ihk.common.util.Utils;
import com.hfzy.ihk.common.web.WebResult;
import com.hfzy.ihk.facade.linkcall.entity.flow.config.SpeakingFlow;
import com.hfzy.ihk.facade.linkcall.entity.flow.config.SpeakingFlowStep;
import com.hfzy.ihk.facade.linkcall.entity.flow.config.SpeakingPackage;
import com.hfzy.ihk.facade.linkcall.entity.knowledge.type.IndustryType;
import com.hfzy.ihk.facade.linkcall.enums.CheckStatus;
import com.hfzy.ihk.web.linkcall.biz.KnowledgeBase.type.IndustryTypeBiz;
import com.hfzy.ihk.web.linkcall.dao.SpeakingPackageRepository;
import com.hfzy.ihk.web.linkcall.support.annotation.PreProcessParam;
import com.hfzy.ihk.web.linkcall.utils.UserUtils;
import com.hfzy.ihk.web.linkcall.utils.WebResultUtils;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class SpeakingPackageBiz extends EsBaseServiceImpl<SpeakingPackage> {
    @Autowired
    SpeakingPackageRepository speakingPackageRepository;
    @Autowired
    SpeakingFlowBiz speakingFlowBiz;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    IndustryTypeBiz industryTypeBiz;

    public static Logger logger = LoggerFactory.getLogger(SpeakingPackageBiz.class);

    @Override
    protected ElasticsearchCrudRepository getReposity() {
        return speakingPackageRepository;
    }

    public WebResult addSpeakingPackage(SpeakingPackage speakingPackage){
        WebResult webResult = null;
        speakingPackage.setCreateTime(new Date());
        speakingPackage.setModTime(new Date());
        speakingPackage.setId(UUIDs.base64UUID());
        speakingPackage.setCreateUserId(UserUtils.getCurrentUserId()!=null?UserUtils.getCurrentUserId():0l);
        speakingPackageRepository.save(speakingPackage);
        webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        return webResult;
    }

    @PreProcessParam
    public Page<SpeakingPackage> getSpeakingPackageByPage(Map<String,String> params){
        BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        int pageNum = Integer.valueOf(params.get("page"))-1;
        int pageSize = Integer.valueOf(params.get("pageSize"));
        //添加排序字段
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);
        return getSpeakingPackagePageByCondition(pageNum,pageSize,boolQueryBuilder,fieldSortBuilder);
    }

    public List<SpeakingPackage> getAllSpeakingPackage(){
        Iterable<SpeakingPackage> speakingPackages = speakingPackageRepository.findAll();
        List<SpeakingPackage> speakingPackageList = Lists.newArrayList(speakingPackages);
        speakingPackageList = injectionsDefaultIndustryTypeIds(speakingPackageList);
        return speakingPackageList;
    }

    @PreProcessParam
    public List<SpeakingPackage> getSpeakingPackageList(Map<String,String> params){
      List<SpeakingPackage> speakingPackageList = null;
        /*  BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .build();
        return elasticsearchTemplate.queryForList(searchQuery,SpeakingPackage.class);*/
        BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        Iterator<SpeakingPackage> iterator = speakingPackageRepository.search(boolQueryBuilder).iterator();
        if (iterator != null) {
            speakingPackageList = new ArrayList<SpeakingPackage>();
            while (iterator.hasNext()) {
                SpeakingPackage next = iterator.next();
                speakingPackageList.add(next);
            }
        }
        speakingPackageList = injectionsDefaultIndustryTypeIds(speakingPackageList);
        return speakingPackageList;
    }


    public SpeakingPackage getSpeakingPackageById(String id){
        Map params = new HashMap();
        params.put("id",id);
        List<SpeakingPackage> speakingPackages = getSpeakingPackageList(params);
        speakingPackages = injectionsDefaultIndustryTypeIds(speakingPackages);
        return Utils.getFirst(speakingPackages);
    }


    public BoolQueryBuilder getQueryBuilderByParams(Map<String,String> params){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        Iterator entries = params.entrySet().iterator();
        while (entries.hasNext()){
            Map.Entry entry = (Map.Entry) entries.next();
            String key = entry.getKey().toString();
            switch (key){
                case "packageName":
                    QueryBuilder projectName = EsQueryUtils.wildcardQuery("packageName", "*"+params.get("packageName")+"*");
                    EsQueryUtils.boolQuery(boolQueryBuilder, EsQueryUtils.BoolType.MUST, projectName);
                    break;
                case "id":
                    QueryBuilder queryBuilder = EsQueryUtils.termQuery("id",params.get("id"));
                    boolQueryBuilder.must(queryBuilder);
                    break;
                case "createUserId":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("createUserId",params.get("createUserId")));
                    break;
                case "ids":
                    boolQueryBuilder.must(EsQueryUtils.termsQuery("id",params.get("ids").split(",")));
                    break;
                case "createTimeStart"://格式：yyyy-MM-dd HH:mm:ss
                    boolQueryBuilder.must(EsQueryUtils.rangeQuery("createTime", params.get("createTimeStart"),
                            null, true, false));
                    break;
                case "createTimeEnd":
                    boolQueryBuilder.must(EsQueryUtils.rangeQuery("createTime", null,
                            params.get("createTimeEnd"), false, true));
                    break;
                case "packageType":
                    boolQueryBuilder.must(QueryBuilders.termQuery("packageType", params.get("packageType")));
                    break;
                case "speakingPackageUseage":
                    boolQueryBuilder.must(QueryBuilders.termQuery("speakingPackageUseage", params.get("speakingPackageUseage")));
                    break;
                case "checkStatus":
                    boolQueryBuilder.must(QueryBuilders.termQuery("checkStatus.keyword", CheckStatus.fromValue(params.get("checkStatus")).name()));
                    break;
                case "hadIndustryTypeId":
                    EsQueryUtils.boolQuery(boolQueryBuilder, EsQueryUtils.BoolType.MUST, EsQueryUtils.wildcardQuery("hadIndustryTypeId", "*"+params.get("hadIndustryTypeId")+"*"));
                    break;
                default:
                    break;
            }
        }
        return boolQueryBuilder;
    }

    public Page<SpeakingPackage> getSpeakingPackagePageByCondition(int pageNum,int pageSize,BoolQueryBuilder boolQueryBuilder,FieldSortBuilder fieldSortBuilder){
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).withSort(fieldSortBuilder).withPageable(PageRequest.of(pageNum,pageSize));
        return speakingPackageRepository.search(builder.build());
    }

    public WebResult saveSpeakingPackage(SpeakingPackage speakingPackage){
        WebResult webResult = null;
        if(!Utils.isNullString(speakingPackage.getId())){
            speakingPackage.setModTime(new Date());
            update(speakingPackage);
        }else{
            webResult = WebResultUtils.getFailCharWebResult("参数异常");
        }
        webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        return webResult;
    }

    public WebResult deleteSpeakingPackageById(String id){
        WebResult webResult = null;
        List<SpeakingFlow> speakingFlows = speakingFlowBiz.getSpeakingFlowListByPackageId(id);
        if(speakingFlows!=null && !speakingFlows.isEmpty()){
            for(SpeakingFlow speakingFlow:speakingFlows){
                speakingFlowBiz.deleteSpeakingFlowById(speakingFlow.getId());
            }
        }
        boolean flag = deleteById(id);
        if(flag){
            webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        }else{
            webResult = WebResultUtils.getFailCharWebResult("参数异常");
        }
        return  webResult;
    }




    public WebResult updateSomeFields(String id,Map<String,Object> updateMap){
        //更新数据库
        WebResult result = WebResultUtils.getFailCharWebResult("");
        try{
            speakingPackageRepository.updateSomeFields(id,SpeakingPackage.class,updateMap);
            result.setCode(GlobalStatic.CODE_1);
            result.setMsg("成功");
        }catch (Exception e){
            result = WebResultUtils.getExceptionCharWebResult("");
        }
        return result;
    }

    public List<SpeakingPackage> injectionsDefaultIndustryTypeIds(List<SpeakingPackage> speakingPackages){
        try{
            if(speakingPackages!=null && !speakingPackages.isEmpty()){
                Map<String,String> params = new HashMap<>();
                params.put("businessTypeBaseId","AWfjFSALTTemOBuU7fwJ");//默认加载通用型的 行业类别
                List<IndustryType> industryTypes = industryTypeBiz.getIndustryTypesList(params);
                if(industryTypes!=null && !industryTypes.isEmpty()){
                    List<String> defaultIndustryTypeIds = industryTypes.stream().map(it->it.getId()).collect(Collectors.toList());
                    speakingPackages.forEach(it->{
                        it.setDefaultIndustryTypeIds(defaultIndustryTypeIds);
                    });
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("加载默认的 行业类别异常 "+e.getMessage());
        }
        return speakingPackages;
    }

}
